package com.vpclub.service;

import com.vpclub.dao.BookDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author : leimingchao
 * @Description:
 * @date Date : 2021年06月07日 22:12
 */
@Service
public class BookService {
    @Autowired
    private BookDao bookDao;

    /**
     * 结账：传入哪个用户买了哪本书
     *
     * @param username
     * @param isbn     事务细节：
     *                 isolation--Isolation:事务隔离级别

     *                 noRollbackFor--Class[]：哪些异常事务可以不回滚
     *                 noRollbackForClassName--String[]（String全类名）：

     *                 rollbackFor---Class[]：哪些异常事务需要回滚
     *                 noRollbackForClassName--String[]

     *                 异常分类：
     *                 运行时异常（非检查异常）：可以不用处理;
     *                 默认都回滚

     *                 编译时异常（检查异常）：要么try-catch；要么在方法上声明throws
     *                 默认不回滚

     *                 事务的回滚：默认发生运行时异常都回滚，发生编译时异常不会回滚
     *                 noRollbackFor：哪些异常事务可以不回滚;(可以让原来默认回滚的异常给他不回滚)
     *                 noRollbackFor = {ArithmeticException.class,NullPointerException.class}
     *                 noRollbackForClassName
     *                 noRollbackForClassName={"java.lang.ArithmeticException","java.lang.NullPointerException"}

     *                 rollbackFor:原本不回滚（原本编译时异常是不回滚的）的异常指定让其回滚
     *                 rollbackFor = {FileNotFoundException.class}
     *                 noRollbackForClassName
     *                 noRollbackForClassName={"java.lang.FileNotFoundException"}
     *                 <p>
     *                 readOnly--boolean：设置事务为只读事务
     *                 可以进行事务优化
     *                 readOnly=true：加快查询速度，不用管事务那一堆操作了

     *                 timeout--int(秒为单位)：超时：事务超出指定执行时长后自动终止并回滚

     *                 propagation--Propagation：事务的传播行为
     *                 传播行为（事务的传播+事务的行为）
     *                 如果有多个事务进行嵌套运行，子事务是否要和大事物公用一个事务
     *                 AService{
     *                 tx_a(){
     *                 //a的一些方法
     *                 tx_b(){}
     *                 tx_c(){}
     *                 }
     *                 }
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void checkOut(String username, String isbn) {
        //1.减库存
        bookDao.updateStock(isbn);
        int price = bookDao.getPrice(isbn);
        //2.减余额
        bookDao.updateBalance(username, price);

    }


    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void updatePrice(String isbn, int price) {
        bookDao.updatePrice(isbn, price);
        // int i = 10 / 0;
    }

    /**
     * 根据业务的特性，进行调整
     *
     * @param isbn
     * @return
     */
    @Transactional(readOnly = true)
    public int getPrice(String isbn) {
        int price = bookDao.getPrice(isbn);
        return price;
    }

    @Transactional
    public void mulTX() {
        checkOut("Tom", "ISBN-001");
        updatePrice("ISBN-002", 998);
        int i = 10 /0;
    }
}
